package com.atguigu.spring.controller;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

@RestController
public class FileController {

    @RequestMapping("/upload/file")
    public String uploadFile(@RequestPart("picture") MultipartFile file) throws IOException {

        if (file.isEmpty()) {
            return "上传的文件为空";
        }

        String contentType = file.getContentType();
        System.out.println("contentType = " + contentType);

        String inputName = file.getName();
        System.out.println("inputName = " + inputName);

        String originalFilename = file.getOriginalFilename();
        System.out.println("originalFilename = " + originalFilename);

        byte[] bytes = file.getBytes();
        System.out.println("bytes = " + bytes);

        InputStream inputStream = file.getInputStream();
        System.out.println("inputStream = " + inputStream);

        long size = file.getSize();
        System.out.println("size = " + size);

        return "ok";
    }

    @RequestMapping("/upload/multi/file/same/name")
    public String uploadMultiFileSameName(@RequestPart("picture") List<MultipartFile> pictureList) {

        for (MultipartFile multipartFile : pictureList) {
            if (!multipartFile.isEmpty()) {
                String originalFilename = multipartFile.getOriginalFilename();
                System.out.println("originalFilename = " + originalFilename);
            }
        }

        return "ok";
    }

    @RequestMapping("/upload/multi/file/different/name")
    public String uploadMultiFileDifferentName(
            @RequestPart("picture") MultipartFile picture,
            @RequestPart("image") MultipartFile image) {

        String originalFilename = picture.getOriginalFilename();
        System.out.println("originalFilename = " + originalFilename);

        originalFilename = image.getOriginalFilename();
        System.out.println("originalFilename = " + originalFilename);

        return "ok";
    }

    @RequestMapping("/download/file")
    public ResponseEntity<byte[]> downloadFile() throws IOException {

        // 1、通过输入流读取要上传的文件
        String fileName = "aaa.pdf";
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);

        byte[] bytes = inputStream.readAllBytes();

        // 2、封装响应消息头
        // [1]创建 HttpHeaders 对象
        HttpHeaders responseHeaders = new HttpHeaders();

        // [2]封装 Content-Disposition 响应消息头
        // ※为了支持中文文件名，对文件名进行重新编码
        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
        responseHeaders.setContentDispositionFormData("attachment", fileName);

        // [3]设置响应体的长度
        responseHeaders.setContentLength(bytes.length);

        // [4]设置响应体的内容类型
        responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // 3、基于前面准备好的参数创建 ResponseEntity 对象
        return new ResponseEntity<>(bytes, responseHeaders, HttpStatus.OK);
    }

    @GetMapping("/download/large/file")
    public ResponseEntity<StreamingResponseBody> downloadLargeFile() {
        // 示例：流式下载大文件
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=aaa.pdf")
                .contentType(MediaType.APPLICATION_OCTET_STREAM).body(outputStream -> {
                    // 从输入流复制到输出流（如：文件、网络流等）
                    try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("aaa.pdf")) {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }
                });
    }
}
